package com.acane.instagram.ws;

import com.acane.instagram.pojo.Message;
import com.acane.instagram.pojo.NotifyType;
import com.acane.instagram.pojo.User;
import com.acane.instagram.pojo.dto.*;
import com.acane.instagram.service.*;
import com.acane.instagram.utils.MessageUtils;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.sql.Timestamp;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfigurator.class)
@Component
@Slf4j
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class WsServerEndpoint {

    private static Map<String, WsServerEndpoint> onlineUsers = new ConcurrentHashMap<>();

    @Autowired
    private ChatService chatService;

    @Autowired
    private PostService postService;

    @Autowired
    private LikeService likeService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private FollowService followService;

    @Autowired
    private UserService userService;

    @Autowired
    private CommentLikeService commentLikeService;


    private Session session;

    private HttpSession httpSession;
    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        // 将局部的Session对象赋值给成员变量
        this.session = session;
        HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        this.httpSession = httpSession;
        String userName = (String) httpSession.getAttribute("user");
        onlineUsers.put(userName, this);

        // 检查 chatService 是否为 null
        if (chatService == null) {
            log.error("ChatService is not injected correctly.");
            return;
        }
        log.info("onOpen", session.getId());
    }
    private void broadcastAllUsers(String message) {
        Set<String> names = onlineUsers.keySet();
        names.forEach(name -> {
            WsServerEndpoint wsServerEndpoint = onlineUsers.get(name);
            if (wsServerEndpoint != null && wsServerEndpoint.session != null && wsServerEndpoint.session.isOpen()) {
                try {
                    wsServerEndpoint.session.getBasicRemote().sendText(message);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            } else {
                // 如果会话已关闭或不存在，可以考虑从在线用户列表中移除该用户
                onlineUsers.remove(name);
                System.out.println("------------会话已关闭或不存在，用户 " + name + " 已被移除-------------------");
            }
        });
    }

    @OnMessage
    public void onMessage(String messageStr, Session session) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            Message<?> wrapper = mapper.readValue(messageStr, new TypeReference<Message<?>>() {});

            // 直接获取已正确反序列化的data对象
            switch (wrapper.getType()) {
                case CHAT_MESSAGE:
                    handleChatMessage(mapper.convertValue(wrapper.getData(), ChatDTO.class));
                    break;
                // 其他case处理...
                case POST_LIKE:
                    handlePostLike(mapper.convertValue(wrapper.getData(), LikeDTO.class));
                    break;

                case POST_COMMENT:
                    handlePostComment(mapper.convertValue(wrapper.getData(), CommentDTO.class));
                    break;

                case COMMENT_LIKE:
                    handleCommentLike(mapper.convertValue(wrapper.getData(), CommentLikeDTO.class));
                    break;

                case FOLLOW_USER:
                    handleFollows(mapper.convertValue(wrapper.getData(), FollowDTO.class));
                    break;

                default:
                    log.warn("Unknown message type: {}", wrapper.getType());
            }
        } catch (Exception e) {
            log.error("Message processing error", e);
        }
    }

    // 分离处理方法示例
    private void handlePostLike(LikeDTO likeDTO) {
        try {
            System.out.println("-----------------收到点赞消息：" + likeDTO);
            ObjectMapper mapper = new ObjectMapper();
            if (likeService.judgeIfAlreadyLike(likeDTO.getPostId(), likeDTO.getLikerId())) {
                LikeDTO like = likeService.getByPostIdAndLikerId(likeDTO.getPostId(), likeDTO.getLikerId());
                // 更新点赞时间
                likeService.updateTime(like.getId());
                return;
            }
            // 生成唯一 ID 和时间戳
            likeDTO.setId(UUID.randomUUID().toString().replace("-", ""));
            likeDTO.setTimestamp(Timestamp.valueOf(LocalDateTime.now()).toString());

            User user = userService.getUserById(likeDTO.getLikerId());

            // 发送给接收方
            WsServerEndpoint targetUser = onlineUsers.get(user.getUserName());
            Message<LikeDTO> likeDTOMessage = new Message<>();
            likeDTOMessage.setType(NotifyType.POST_LIKE);
            likeDTOMessage.setData(likeDTO);
            // 构建标准消息格式
            String likeNotification = mapper.writeValueAsString(likeDTOMessage);
            if (targetUser != null && targetUser.session.isOpen()) {
                targetUser.session.getBasicRemote().sendText(likeNotification);
            }
            // 保存到数据库

            likeService.save(likeDTO);
            System.out.println("-----------------存进数据库点赞消息：" + likeDTO);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    private void handlePostComment(CommentDTO commentDTO) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            commentDTO.setId(UUID.randomUUID().toString().replace("-", ""));
            commentDTO.setTimestamp(Timestamp.valueOf(LocalDateTime.now()).toString());

            User user = postService.getUserByPostId(commentDTO.getPostId());
            WsServerEndpoint targetUser = onlineUsers.get(user.getUserName());

            Message<CommentDTO> commentDTOMessage = new Message<>();
            commentDTOMessage.setType(NotifyType.POST_COMMENT);
            commentDTOMessage.setData(commentDTO);

            String commentNotification = mapper.writeValueAsString(commentDTOMessage);
            if (targetUser != null && targetUser.session.isOpen()) {
                targetUser.session.getBasicRemote().sendText(commentNotification);
            }
            // 存储到数据库
            System.out.println("-----------------存进数据库评论消息：" + commentDTO);
            //commentService.save(commentDTO);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleCommentLike(CommentLikeDTO commentLikeDTO) {
        try {

            ObjectMapper mapper = new ObjectMapper();
            commentLikeDTO.setId(UUID.randomUUID().toString().replace("-", ""));
            commentLikeDTO.setTimestamp(Timestamp.valueOf(LocalDateTime.now()).toString());

            // 保存到数据库
            if (commentService.judgeIfAlreadyLike(commentLikeDTO.getCommentId(), commentLikeDTO.getLikerId())) {
                // 更新点赞时间
                return;
            }
            commentLikeService.save(commentLikeDTO);
            System.out.println("-----------------存进数据库点赞评论消息：" + commentLikeDTO);
            User user = userService.getUserById(commentService.getById(commentLikeDTO.getCommentId()).getCommenterId());
            WsServerEndpoint targetUser = onlineUsers.get(user.getUserName());

            Message<CommentLikeDTO> commentLikeDTOMessage = new Message<>();
            commentLikeDTOMessage.setType(NotifyType.COMMENT_LIKE);
            commentLikeDTOMessage.setData(commentLikeDTO);

            String commentLikeNotification = mapper.writeValueAsString(commentLikeDTOMessage);
            if (targetUser != null && targetUser.session.isOpen()) {
                targetUser.session.getBasicRemote().sendText(commentLikeNotification);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void handleFollows(FollowDTO followDTO) {
        try {
            // 获取被关注者的用户名
            String followingId = followDTO.getFollowingId();

            followDTO.setId(UUID.randomUUID().toString().replace("-", ""));
            followDTO.setCreateTime(LocalDateTime.now().toString());
            followDTO.setUpdateTime(LocalDateTime.now().toString());
            // 设置为已关注
            followDTO.setStatus(1);
            followService.save(followDTO);
            // 获取被关注者的用户名
            WsServerEndpoint targetUser = onlineUsers.get(followingId);
            Message<FollowDTO> followDTOMessage = new Message<>();
            followDTOMessage.setType(NotifyType.FOLLOW_USER);
            followDTOMessage.setData(followDTO);
            ObjectMapper mapper = new ObjectMapper();
            String followNotification = mapper.writeValueAsString(followDTOMessage);

            if (targetUser != null && targetUser.session.isOpen()) {
                targetUser.session.getBasicRemote().sendText(followNotification);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    // 分离处理方法示例
    private void handleChatMessage(ChatDTO chatDTO) {
        try {
            String toName = chatDTO.getReceiver();
            String fromName = chatDTO.getSender(); // 确保前端传了 sender

            // 生成唯一 ID 和时间戳
            chatDTO.setId(UUID.randomUUID().toString().replace("-", ""));
            chatDTO.setTimestamp(Timestamp.valueOf(LocalDateTime.now()).toString());

            // 根据内容自动设置类型
            if (chatDTO.getContent().endsWith(".jpg")) {
                chatDTO.setMediaType("image");
            } else if (chatDTO.getContent().endsWith(".mp4")) {
                chatDTO.setMediaType("video");
            } else {
                chatDTO.setMediaType("text");
            }
            System.out.println("-----------------存进数据库聊天消息：" + chatDTO);
            // 保存到数据库
            chatService.saveMessage(chatDTO);


            Message<ChatDTO> chatDTOMessage = new Message<>();
            chatDTOMessage.setType(NotifyType.CHAT_MESSAGE);
            chatDTOMessage.setData(chatDTO);
            // 构建标准消息格式
            String resultMessage = MessageUtils.getMessage(chatDTOMessage, false);
            System.out.println("-----------------后端发送给接收方：" + resultMessage);
            // 发送给接收方
            WsServerEndpoint targetUser = onlineUsers.get(toName);
            if (targetUser != null && targetUser.session.isOpen()) {
                targetUser.session.getBasicRemote().sendText(resultMessage);
            }

            // 关键修复：同时发送给发送方自己（确保自己也能实时看到消息）
            WsServerEndpoint senderUser = onlineUsers.get(fromName);
            if (senderUser != null && senderUser.session.isOpen()) {
                senderUser.session.getBasicRemote().sendText(resultMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    @OnClose
    public void onClose(Session session) {

        log.info("onClose", session.getId());
    }


    private Set getNames() {
        return onlineUsers.keySet();
    }
}
